Por que Julia?

Por que escolher Julia?

  • A linguagem de programação Julia, lançada oficialmente em 2012, tem se destacado como uma alternativa moderna para ciência de dados e computação científica, competindo com linguagens como Matlab, Python e R;
  • É utilizada não apenas na academia, mas também fora dela;
  • Julia é gratuita;
  • Julia oferece desempenho próximo ao de C++, aliado à facilidade de aprendizado e sintaxe simples, comparáveis a Python e R;
  • Julia permite escrever código com símbolos matemáticos diretamente 🤓, facilitando a expressão de conceitos científicos;
  • Julia resolve o problema das duas linguagens 🆒;
  • Porque o projeto Do Zero ao Julia é 100% Unicamper (🕺);
  • Etc.

Do Zero ao Julia

Website do projeto”Do Zero ao Julia”: www.ime.unicamp.br/julialang

Primeiros passos

Primeiros passos

Passo 1: Abrir o Colab https://colab.research.google.com/

Passo 2: Criar novo notebook
Figura 1: Google Colaboratory (Colab)

Primeiros passos

Passo 3: Configurar o Colab

Passo 4: Julia pronto pra ação
Figura 2: Julia no Colab

Primeiros passos

Atribuindo valores a diferentes variáveis e vetores

x = 20;
y = 8.3;
nome = "Julia";
idade = 19;
nomes  = ["Julia", "Lucas", "Pedro", "Carlos", "Maria", "Luisa", "Marcelo", "Camila"];
idades = [19, 20, 18, 22, 21, 19, 17, 23];
peso   = [65.5, 70.5, 65.2, 70.1, 65.1, 65.4, 65.3, 65.2];

Primeiros passos

Acessando aos elementos dos vetores

idades[2]
20
nomes[3]
"Pedro"

Primeiros passos

Qual a diferença entre

log(idades)

e

log.(idades)

Qual código está correto?

idades + 1    
idades .+ 1  

Observação: O . (dot) faz com que a operação seja feita em todos os elementos do vetor.

Primeiros passos

# Matrizes
A = [1.0 2.0 3.0; 4.0 5.0 6.0]   # 2x3 de Float64
B = [1 2 3; 4 5 6]  # 2x3 de Int
Z = zeros(3, 4) # Matriz de zeros
O = ones(Int, 2, 5) # Matriz de uns
R = rand(3, 3)   # Aleatória uniforme [0,1)
N = randn(3, 3)  # Aleatória normal padrão

Como acessar aos elementos da matriz?

A[1, 2]         # elemento da 1ª linha, 2ª coluna
A[2, :]         # linha 2 inteira
A[:, 3]         # coluna 3 inteira
A[1:2, 2:3]     # submatriz
A[1, 2] = 10.0  # alterar valor

Primeiros passos

Instalar pacotes:

using Pkg
Pkg.add("Statistics")
Pkg.add("Random")

Carregar pacotes:

using LinearAlgebra
using Statistics
using Random

Nota

Boas práticas em Julia são:

  1. Carregar os pacotes logo no começo do script
  2. Carregar cada pacote um a um (linha a linha)
  3. Carregar os pacotes em ordem alfabetica.

Se quiser saber mais acerca de boas práticas, veja aqui.

Importação de dados

Importação de dados

Nesta seção veremos como importar nossos datasets, estando eles armazenados localmente ou online. Também veremos a diferença na leitura de diferentes formatos, como .csv, .txt e .xlsx.

Julia conta com diversos pacotes para leitura de datasets, dentre eles:

import Pkg

Pkg.add("DataFrames");
Pkg.add("CSV")
Pkg.add("XLSX")
  • DataFrames : Manipulação e análise de dados em formato tabular, similar ao pandas (Python) ou data.frame (R);
  • CSV : Leitura e escrita de arquivos CSV de forma rápida e eficiente;
  • XLSX : Leitura e escrita de arquivos Excel (.xlsx).

Funções básicas

Com os pacotes necessários instalados, agora vejamos como as funções de leitura funcionam:

using DataFrames, CSV, XLSX

# .csv
df_csv = CSV.read("caminho/dados.csv", DataFrame)

# .txt
df_txt = CSV.read("caminho/dados.txt", DataFrame, delim=';')

# .xlsx
sheets = XLSX.readxlsx("caminho/dados.xlsx")
df_xlsx = DataFrame(sheets)

Funções básicas

Podemos usar a função download() para baixar um arquivo temporariamente e retorna o caminho local onde ele foi salvo.

Ex.:

dados_csv = CSV.read(download(url), DataFrame, delim=';')

first(dados_csv, 5) # Podemos usar a função first() para visualizar as primeiras linhas do dataset

Leitura da base de dados

Agora, vamos ler os dados que usaremos na aula de hoje.

```{julia}
begin
    import Pkg
    redirect_stdout(devnull) do
        redirect_stderr(devnull) do
            Pkg.add("DataFrames")
            Pkg.add("CSV")
            Pkg.add("XLSX")
        end
    end
end
```
using CSV
using DataFrames

file = "https://raw.githubusercontent.com/Arthur-Dionizio/minicurso-julia/main/datasets/dataset.csv";
dados = CSV.read(download(file), DataFrame);
first(dados, 5)
5×21 DataFrame
 Row │ Column1  track_id                artists                 album_name     ⋯
     │ Int64    String31                String?                 String?        ⋯
─────┼──────────────────────────────────────────────────────────────────────────
   1 │       0  5SuOikwiRyPMVoIQDJUgSV  Gen Hoshino             Comedy         ⋯
   2 │       1  4qPNDBW1i3p13qLCt0Ki3A  Ben Woodward            Ghost (Acousti
   3 │       2  1iJBSr7s7jYXzM8EGcbK5b  Ingrid Michaelson;ZAYN  To Begin Again
   4 │       3  6lfxq3CG4xtTiEg7opyCyx  Kina Grannis            Crazy Rich Asi
   5 │       4  5vjLSffimiIP26QG5WcN2K  Chord Overstreet        Hold On        ⋯
                                                              18 columns omitted

Leitura da base de dados

using DataFrames
using TidierData

@chain dados begin
    @slice(1:6)
end
6×21 DataFrame
 Row │ Column1  track_id                artists                 album_name     ⋯
     │ Int64    String31                String?                 String?        ⋯
─────┼──────────────────────────────────────────────────────────────────────────
   1 │       0  5SuOikwiRyPMVoIQDJUgSV  Gen Hoshino             Comedy         ⋯
   2 │       1  4qPNDBW1i3p13qLCt0Ki3A  Ben Woodward            Ghost (Acousti
   3 │       2  1iJBSr7s7jYXzM8EGcbK5b  Ingrid Michaelson;ZAYN  To Begin Again
   4 │       3  6lfxq3CG4xtTiEg7opyCyx  Kina Grannis            Crazy Rich Asi
   5 │       4  5vjLSffimiIP26QG5WcN2K  Chord Overstreet        Hold On        ⋯
   6 │       5  01MVOl9KtVTNfFiBU9I7dc  Tyrone Wells            Days I Will Re
                                                              18 columns omitted

Leitura da base de dados

Conhecendo o dataset

  1. track_name: Nome da faixa;
  2. artists: Os nomes dos artistas que interpretaram a faixa. Se houver mais de um artista, eles serão separados por ‘;’ ;
  3. album_name: O nome do álbum de onde a faixa pertence;
  4. popularity: A popularidade de uma faixa é um valor entre 0 e 100, sendo 100 o mais popular, sendo calculada a partir (de forma geral) do número de streams daquela faixa, e o quão recente foram essas streams;
  5. duration_ms: A duração da faixa em milissegundos;
  6. danceability: A dançabilidade descreve o quão adequada uma faixa é para dançar com base em uma combinação de elementos musicais, incluindo andamento, estabilidade do ritmo, força da batida e regularidade geral. Um valor de 0,0 é o menos dançante e 1,0 o mais dançante;

Leitura da base de dados

Conhecendo o dataset

  1. energy: Energia é uma medida de 0,0 a 1,0 e representa uma medida perceptual de intensidade e atividade. Normalmente, músicas energéticas parecem rápidas, altas e barulhentas. Por exemplo, o death metal tem alta energia, enquanto um prelúdio de Bach tem baixa pontuação na escala;
  2. loudness: O volume total de uma faixa em decibéis (dB);
  3. speechiness: Detecta a presença de palavras faladas em uma faixa. Quanto mais exclusivamente semelhante à fala for a gravação (por exemplo, talk show, audiolivro, poesia), mais próximo de 1,0 será o valor do atributo. Valores acima de 0,66 descrevem faixas que provavelmente são compostas inteiramente de palavras faladas. Valores entre 0,33 e 0,66 descrevem faixas que podem conter música e fala, seja em seções ou em camadas, incluindo casos como rap. Valores abaixo de 0,33 provavelmente representam música e outras faixas que não se assemelham à fala.
  4. acousticness: Uma medida de confiança de 0,0 a 1,0 para determinar se a faixa é acústica. 1,0 representa alta confiança de que a faixa é acústica.

Leitura da base de dados

Conhecendo o dataset

  1. valence: Uma medida de 0,0 a 1,0 que descreve a positividade musical transmitida por uma faixa. Faixas com alta valência soam mais positivas (por exemplo, felizes, alegres, eufóricas), enquanto faixas com baixa valência soam mais negativas (por exemplo, tristes, deprimidas, raivosas);
  2. tempo: O andamento estimado geral de uma faixa em batidas por minuto (BPM);
  3. track_genre: O gênero da faixa;
  4. instrumentalness: Prevê se uma faixa não contém vocais. Sons de “Ooh” e “aah” são tratados como instrumentais neste contexto. Faixas de rap ou palavra falada são claramente “vocais”. Quanto mais próximo o valor de instrumentalidade estiver de 1,0, maior a probabilidade de a faixa não conter conteúdo vocal.
  5. liveness: Detecta a presença de público na gravação. Valores mais altos de ao vivo representam uma probabilidade maior de que a faixa tenha sido tocada ao vivo. Um valor acima de 0,8 fornece alta probabilidade de que a faixa seja ao vivo.

Manipulação de banco de dados

Tidier.jl

A biblioteca Tidier.jl possui vários pacotes que auxiliam na manipulação e análise de datasets. Para quem está vindo do R, esses pacotes são bem similares e intuitivos. Aqui estão alguns dos pacotes:

  • TidierData : Implementação 100% Julia dos pacotes dplyr e tidyr do R. Usado na tranformação e manipulação dos dados;
  • TidierPlots : Implementação 100% Julia do pacote ggplot2 do R;
  • TidierStrings : O objetivo deste pacote é replicar o stringr do R em Julia de uma forma que funcione com o Tidier ou como uma função autônoma.

Acessem o link https://tidierorg.github.io/Tidier.jl/v1.6.1/ para mais informações!

Pacote TidierData.jl

Para a nossa análise de hoje, vamos utilizar principalmente o pacote TidierData.

Funções Macro

Para suportar a programação no estilo R, o TidierData.jl é implementado usando macros. Isso ocorre porque as macros são capazes de “capturar” o código antes de executá-lo, o que permite que o pacote suporte “expressões tidy” semelhantes ao R que, de outra forma, não seriam consideradas código Julia válido.

Pacote TidierData.jl

using TidierData

@chain dados begin
    @filter(popularity > 50)
    @arrange(desc("energy"))
    @select(track_name, popularity, energy, acousticness)
    @slice(1:5)
end
5×4 DataFrame
 Row │ track_name                   popularity  energy   acousticness
     │ String?                      Int64       Float64  Float64
─────┼────────────────────────────────────────────────────────────────
   1 │ Meeresrauschen zum Schlafen          52    0.999       0.554
   2 │ Voodoo People                        56    0.998       0.00128
   3 │ Bleed                                60    0.998       8.12e-6
   4 │ Wait A Minute                        58    0.998       0.0496
   5 │ Hooked                               52    0.998       0.0207

Pacote TidierData.jl

Para quem já está familiarizado com a linguagem R, a função @chain() é similar ao pipeline %>% ou |>, usado para encadear várias operações em sequência no mesmo conjunto de dados.

  • @filter() : Filtra as linhas com base em uma restrição;
  • @arrange() : Ordena as linhas com base em uma coluna (desc() para definir ordem crescente ou decrescente);
  • @select() : Seleciona as colunas de interesse;
  • @slice() : Seleciona as linhas para visualização.

Obs.: A função desc() é uma função auxiliar.

Pacote TidierData.jl

Existem algumas funções auxiliares do pacote que é importante citarmos:

  • across() : Aplica uma função a várias colunas de uma vez;
  • n() e row_number() : Retornam o número total de linhas ou o número da linha;
  • replace_missing() : Substitui valores ausentes em uma coluna por um valor especificado.

Pacote TidierData.jl

Outras funções auxiliares de outros pacotes que vale mencionar:

  • dropmissing() : Remove as linhas que contêm valores faltantes (missing);
  • unique() : Retorna os valores distintos únicos de um vetor ou coluna, removendo duplicatas;
  • nrow() : Retorna o número de linhas de um DataFrame ou matriz;
  • any() : Testa se pelo menos um elemento de uma coleção (ou resultado de uma condição) é verdadeiro; retorna true ou false.

Dica

Use a função any() e a função ismissing no formato row -> any(ismissing, row) para verificar se há colunas sem informação. Nesse caso, a função filter() da base do Julia é mais eficiente, no formato filter(condição, dados).

Pacote TidierData.jl

Limpeza do dataset do Spotify: Tratando valores faltantes

faltantes = filter(row -> any(ismissing, row), dados)
1×21 DataFrame
 Row │ Column1  track_id                artists  album_name  track_name  popul ⋯
     │ Int64    String31                String?  String?     String?     Int64 ⋯
─────┼──────────────────────────────────────────────────────────────────────────
   1 │   65900  1kR4gIb7nGxHPI3D2ifs59  missing  missing     missing           ⋯
                                                              16 columns omitted
@chain faltantes begin
    @slice(1)
end
1×21 DataFrame
 Row │ Column1  track_id                artists  album_name  track_name  popul ⋯
     │ Int64    String31                String?  String?     String?     Int64 ⋯
─────┼──────────────────────────────────────────────────────────────────────────
   1 │   65900  1kR4gIb7nGxHPI3D2ifs59  missing  missing     missing           ⋯
                                                              16 columns omitted

Pacote TidierData.jl

Vamos remover as linhas que possuem valores faltantes.

dados = @chain dados begin
    dropmissing()
end
113999×21 DataFrame
    Row │ Column1  track_id                artists                             ⋯
        │ Int64    String31                String                              ⋯
────────┼───────────────────────────────────────────────────────────────────────
      1 │       0  5SuOikwiRyPMVoIQDJUgSV  Gen Hoshino                         ⋯
      2 │       1  4qPNDBW1i3p13qLCt0Ki3A  Ben Woodward
      3 │       2  1iJBSr7s7jYXzM8EGcbK5b  Ingrid Michaelson;ZAYN
      4 │       3  6lfxq3CG4xtTiEg7opyCyx  Kina Grannis
      5 │       4  5vjLSffimiIP26QG5WcN2K  Chord Overstreet                    ⋯
      6 │       5  01MVOl9KtVTNfFiBU9I7dc  Tyrone Wells
      7 │       6  6Vc5wAMmXdKIAM7WUoEb7N  A Great Big World;Christina Agui…
      8 │       7  1EzrEOXmMH3G43AXT1y7pA  Jason Mraz
   ⋮    │    ⋮               ⋮                             ⋮                   ⋱
 113993 │  113993  4OkMK49i3NApR1KsAIsTf6  Chris Tomlin                        ⋯
 113994 │  113994  4WbOUe6T0sozC7z5ZJgiAA  Lucas Cervetti
 113995 │  113995  2C3TZjDRiAzdyViavDJ217  Rainy Lullaby
 113996 │  113996  1hIz5L4IB9hN3WRYPOCGPw  Rainy Lullaby
 113997 │  113997  6x8ZfSoqDjuNa5SVP5QjvX  Cesária Evora                       ⋯
 113998 │  113998  2e6sXL2bYv4bSz6VTdnfLs  Michael W. Smith
 113999 │  113999  2hETkH7cOfqmz3LqZDHZf5  Cesária Evora
                                              18 columns and 113984 rows omitted

Pacote TidierData.jl

Verificaremos possíveis faixas duplicadas, e retirá-las caso haja alguma.

nrow(unique(dados, :track_id)), nrow(dados)
(89740, 113999)
dados = unique(dados, :track_id)
89740×21 DataFrame
   Row │ Column1  track_id                artists                            a ⋯
       │ Int64    String31                String                             S ⋯
───────┼────────────────────────────────────────────────────────────────────────
     1 │       0  5SuOikwiRyPMVoIQDJUgSV  Gen Hoshino                        C ⋯
     2 │       1  4qPNDBW1i3p13qLCt0Ki3A  Ben Woodward                       G
     3 │       2  1iJBSr7s7jYXzM8EGcbK5b  Ingrid Michaelson;ZAYN             T
     4 │       3  6lfxq3CG4xtTiEg7opyCyx  Kina Grannis                       C
     5 │       4  5vjLSffimiIP26QG5WcN2K  Chord Overstreet                   H ⋯
     6 │       5  01MVOl9KtVTNfFiBU9I7dc  Tyrone Wells                       D
     7 │       6  6Vc5wAMmXdKIAM7WUoEb7N  A Great Big World;Christina Agui…  I
     8 │       7  1EzrEOXmMH3G43AXT1y7pA  Jason Mraz                         W
   ⋮   │    ⋮               ⋮                             ⋮                    ⋱
 89734 │  113993  4OkMK49i3NApR1KsAIsTf6  Chris Tomlin                       S ⋯
 89735 │  113994  4WbOUe6T0sozC7z5ZJgiAA  Lucas Cervetti                     F
 89736 │  113995  2C3TZjDRiAzdyViavDJ217  Rainy Lullaby                      #
 89737 │  113996  1hIz5L4IB9hN3WRYPOCGPw  Rainy Lullaby                      #
 89738 │  113997  6x8ZfSoqDjuNa5SVP5QjvX  Cesária Evora                      B ⋯
 89739 │  113998  2e6sXL2bYv4bSz6VTdnfLs  Michael W. Smith                   C
 89740 │  113999  2hETkH7cOfqmz3LqZDHZf5  Cesária Evora                      M
                                               18 columns and 89725 rows omitted

Análise Exploratória de Dados (EDA)

EDA

  • Julia torna possível compreender e explorar conjuntos de dados, identificando padrões, tendências e possíveis outliers antes da modelagem.
  • Nesse tópico, iremos explorar algumas estatísticas resumo (média, mediana, desvio-padrão, etc.) e algumas distribuições (discretas e contínuas).
  • Os pacotes Statistics.jl, StatsBase.jl, DataFrames.jl e TidierData.jl serão essenciais para a análise 🆒.
using DataFrames
using StatsBase
using Statistics
using TidierData

Medidas de tendência central

  • mean(x): media
  • median(x): mediana
  • mode(x): moda (pacote StatsBase.jl)

Medidas de dispersão

  • var(x): variância amostral
  • std(x): desvio padrão
  • minimum(x): mínimo
  • maximum(x): máximo
  • quantile(x, p): p-éssimo quantil empírico

Contagem e frequência

  • length(x): número de elementos
  • count(cond, x): conta elementos que satisfazem uma condição cond
  • countmap(x): cria uma tabela de frequências (pacote StatsBase.jl)

Informações resumidas

  • describe(df): fornece estatísticas descritivas de um data frame
  • cor(x, y): correlação entre duas variáveis x e y
  • cov(x, y): covariância das variáveis x e y

Visualização de dados

Julia oferece diversas bibliotecas para criar visualizações estatísticas de forma simples e flexível, permitindo a análise e interpretação de dados de maneira visual. Algumas bibliotecas populares incluem Plots.jl, StatsPlots.jl, Makie.jl e Gadfly.jl.

using Gadfly
using Makie
using Plots
using StatsPlots
  • bloxplot(x): gráfico de caixas
  • bar(x): gráfico de barras
  • histogram(x): histograma
  • scatter(x): gráfico de dispersão
  • density(x): gráfico de densidade

Modelar

Regressão e Classificação

Referências